<template>
  <div id="map" class="map-container"></div>
</template>

<script lang="ts">
import { defineComponent, onMounted, onUnmounted } from 'vue';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import ImageTile from 'ol/source/ImageTile';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import { fromLonLat, toLonLat } from 'ol/proj';
import Style from 'ol/style/Style';
import Circle from 'ol/style/Circle';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
import Collection from 'ol/Collection';
import { defaults as DefaultControls } from 'ol/control';

import { BoxSelectHandler, OnBoxSelectEndCallback } from '../utils/BoxSelectHandler';

export default defineComponent({
  name: 'BoxSelectMap',
  setup() {
    let map: Map | null = null;
    let boxSelectHandler: BoxSelectHandler | null = null;

    onMounted(() => {
      // 1. 创建高德地图卫星图层
      const gaodeSatelliteLayer = new TileLayer({
        source: new ImageTile({
          url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
        }),
        properties: {
          name: '高德卫星图',
        },
      });

      // 2. 创建高德地图路网图层 (可以叠加在卫星图之上)
      const gaodeRoadLayer = new TileLayer({
        source: new ImageTile({
          url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8',
        }),
        properties: {
          name: '高德路网图',
        },
      });

      // 3. 创建一个用于放置可框选特征的矢量源
      const vectorSource = new VectorSource<Feature<Point>>({
        features: [],
      });

      // 4. 创建一个矢量层来渲染矢量源中的特征
      const vectorLayer = new VectorLayer({
        source: vectorSource,
        properties: {
          name: '可框选特征层',
        },
        style: new Style({
          image: new Circle({
            radius: 7,
            fill: new Fill({
              color: 'rgba(255, 0, 0, 0.6)',
            }),
            stroke: new Stroke({
              color: 'rgba(255, 0, 0, 1)',
              width: 2,
            }),
          }),
        }),
      });

      // 5. 生成一些随机点特征作为示例
      const numFeatures = 50;
      const extent = fromLonLat([80, 15]).concat(fromLonLat([130, 50]));
      for (let i = 0; i < numFeatures; i++) {
        const longitude = extent[0] + (Math.random() * (extent[2] - extent[0]));
        const latitude = extent[1] + (Math.random() * (extent[3] - extent[1]));
        const pointFeature = new Feature({
          geometry: new Point([longitude, latitude]),
          id: i + 1,
          name: `Feature ${i + 1}`,
        });
        vectorSource.addFeature(pointFeature);
      }

      // 6. 初始化 OpenLayers 地图
      map = new Map({
        target: 'map',
        layers: [
          gaodeSatelliteLayer,
          gaodeRoadLayer,
          vectorLayer,
        ],
        view: new View({
          center: fromLonLat([105, 35]),
          zoom: 5,
        }),
        controls: DefaultControls({
          zoom: false,
          rotate: false,
          attribution: false,
        }).extend([]),
      });

      // 8. 定义框选结束后的处理逻辑
      const onBoxSelectEnd: OnBoxSelectEndCallback = (selectedFeatures) => {
        console.log('--- 框选结束后的业务处理 ---');
        if (selectedFeatures.getLength() > 0) {
          console.log('业务处理：新框选到的特征:');
          selectedFeatures.forEach(feature => {
            const geometry = feature.getGeometry() as Point;
            const coordinates = toLonLat(geometry.getCoordinates());
            console.log(`  ID: ${feature.get('id')}, 名称: ${feature.get('name')}, 坐标: [${coordinates[0].toFixed(4)}, ${coordinates[1].toFixed(4)}]`);
          });
        } else {
          console.log('业务处理：没有特征被框选。');
        }
      };

      // 9. 实例化 BoxSelectHandler
      boxSelectHandler = new BoxSelectHandler({
        map: map,
        vectorSource: vectorSource,
        onBoxSelectEnd: onBoxSelectEnd,
        selectStyle: new Style({
          image: new Circle({
            radius: 8,
            fill: new Fill({
              color: 'rgba(0, 255, 255, 0.8)',
            }),
            stroke: new Stroke({
              color: 'rgba(0, 255, 255, 1)',
              width: 3,
            }),
          }),
        }),
      });
    });

    onUnmounted(() => {
      if (map) {
        map.setTarget(undefined);
        map = null;
      }
      if (boxSelectHandler) {
        boxSelectHandler.destroy();
        boxSelectHandler = null;
      }
    });

    return {};
  },
});
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 600px;
  background-color: #f0f0f0;
}
</style> 